package hyl.ext.ws.msg;

import java.io.ByteArrayOutputStream;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;

import hyl.core.run.IDo1;
/**
 * 消息流对象
 * 
 * 把消息字节 添加到消息流对象 在输出 消息包对象
 * 
 * @author 37798955@qq.com
 *
 */
public class MsgpgStream extends ByteArrayOutputStream {
	
	public MsgpgStream() {}
	public static MsgpgStream getInstance() {
		return new MsgpgStream() ; 
	}
	/**
	 * 移除开始位置左侧的数据,保留开始位置右侧的数据 包含开始位置
	 * 
	 * @param 开始位置
	 * @return
	 */
	void f截断(int 开始位置) {
		//这里必须用 count 不能用buf.length 原因是 buf是缓冲区大小 不是实际字节长度
		if (开始位置 < 0)			
			开始位置 = count+开始位置;
		int 长度 = count - 开始位置;		
		byte[] 剩余 = new byte[长度];
		if (长度>0)
			System.arraycopy(buf, 开始位置, 剩余, 0, 长度);
		// System.arraycopy(目标, 0, buf, 0, 长度);
		buf = 剩余;//剩余字节
		count = 长度;//剩余长度
	}

	/**
	 * 添加 数据接收时 的数据碎片
	 * 
	 * ??? 未测试先不用
	 * 
	 * @param readBuffer
	 * @param call
	 */
	public MsgpgStream add碎片(ByteBuffer readBuffer) {
		readBuffer.flip();
		int size = readBuffer.limit();
		byte[] bytes = new byte[size];
		readBuffer.get(bytes);
		readBuffer.clear();
		return add碎片(bytes);
	}

	/**
	 * 添加 数据接收时 的数据碎片
	 * 
	 * @param b
	 * @return
	 */
	public MsgpgStream add碎片(byte b[]) {
		try {
			write(b, 0, b.length);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return this;
	}

	/**
	 * 添加一个Netpg1 对象的字节串, 到字节发送流中
	 *
	 */
	public MsgpgStream add包(Msgpg pg) {
		try {
			if (pg.length() == 0)
				return this;
			byte[] bb = pg.toSendBytes();
			write(bb, 0, bb.length);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return this;
	}

	/**
	 * 遍历流 取出 每个 Netpg1
	 * 
	 * @param call
	 */
	public void foreach(IDo1<Msgpg> call) {
		// 第一个 字节一定是 数据包的长度
		synchronized (buf) {
			while (true) {
				// 有数据就处理
				if (count== 0)
					return;
				//MyFun.print("v",buf.length,count);
				Msgpg pg = Msgpg.create中转消息();				
				pg.ini(buf);
				int pglen = pg.length();
				if (pglen <=4)
					return;
				if (pglen > 4)
					call.run(pg);
				f截断(pglen);
				// MyFun.print("v",pglen,count);
			}
		}
	}

	List<Msgpg> li = new ArrayList<>();

	public void clearList() {
		li.clear();
	}

	/**
	 * 把流字节 转为 WsMsgB类型的包list
	 * 
	 * @return
	 */
	public List<Msgpg> toList() {
		synchronized (buf) {
			while (true) {
				// 有数据就处理
				if (count == 0)
					return li;
				// MyFun.print("v",buf.length,count);
				Msgpg pg =new Msgpg();//消息类型是未知的
				pg.ini(buf);
				int pglen = pg.length();
				//MyFun.print("v",pglen);
				if (pglen <= 4)
					return li;
				if (pglen > 4)
					li.add(pg);
				f截断(pglen);
				// MyFun.print("v",pglen,count);
			}
		}
	}
}
